	.orig	0x200
SysStackTop:
	.orig	0x200
	
	; Save registers to system stack
	addi    rd,rd,-32
	sw		t0,0(rd)
	sw		t1,4(rd)
	sw		t2,8(rd)
	sw		t3,12(rd)
	sw		a0,16(rd)
	sw		a1,20(rd)
	sw		a2,24(rd)
	sw		a3,28(rd)

Timer:
	rctl	a1,ctl1
	;Check to see if it's a timer interrupt
	eqi		t1,a1,1
	beqz	t1,Key			;dev isn't timer, try key

	; Clear the IP bit in TCTL
	lw 		a1,0xf100(t0)
	andi 	a2,a1,0x2
	xor 	a1,a1,a2
	sw 		a1,0xf100(t0)
	
	;It's a timer interrupt
	;is the sw0 on?
	lw		t1,0xF004(t0)	;t1 = switches
	andi	t1,t1,1			;t1 = mask switch 0
	beqz	t1,TClearFlash	;if sw0 is off, clear this
	;if sw0 is on, inc HalfSec
	lw		t2,HalfSec(t0)	;t2 = HalfSec
	addi	t2,t2,1			;HalfSec++
	sw		t2,HalfSec(t0)	;store HalfSec
	eqi		t3,t2,50		;if(HalfSec == 50)
	beqz	t3,TCont1
	;flash seccount
	sw		t0,HalfSec(t0)	;HalfSec = 0
	lw		t2,LEDVal(t0)	;t2 = LEDVal
	xori	t2,t2,0xC0		;flip C0
	sw		t2,LEDVal(t0)	;store LEDVal
	beq		t0,t0,TCont1
	
TClearFlash:
	sw		t0,HalfSec(t0)	;HalfSec = 0
	sw		t0,LEDVal(t0)	;LEDVal = 0
TCont1:
	;inc timercount
	lw		t2,TimerCount(t0);t2 = TimerCount
	addi	t2,t2,1			 ;TimerCount++
	sw		t2,TimerCount(t0);store TimerCount
	eqi		t3,t2,100		 ;if(TimerCount == 100) t3 = 1;
	beqz	t3,DispTimer
	
	;if TimerCount = 100
	;store 0 in timercount
	sw		t0,TimerCount(t0); TimerCount = 0
	;inc seccount
	lw		t2,SecCount(t0)	;t2 = SecCount
	addi	t2,t2,1			;SecCount++
	sw		t2,SecCount(t0)	;Store SecCount
	eqi		t3,t2,60		;if(SecCount == 60) t3 = 0;
	beqz	t3,DispTimer

	;if SecCount = 60
	sw		t0,SecCount(t0)	;SecCount = 0
	;inc minLo
	lw		t2,MinLo(t0)	;t2 = MinLo
	addi	t2,t2,1			;MinLo++
	sw		t2,MinLo(t0)	;Store MinLo
	eqi	t3,t2,10			;if(MinLo == 10) t3 = 0;
	beqz	t3,DispTimer

	;if MinLo = 10
	sw		t0,MinLo(t0)	;MinLo = 0
	;inc MinHi
	lw		t2,MinHi(t0)	;t2 = MinHi
	addi	t2,t2,16		;MinHi++
	sw		t2,MinHi(t0)	;Store MinHi
	eqi	t3,t2,96			;if(MinHi == 6*16) t3 = 0
	beqz	t3,DispTimer
	
	;if MinHi = 6
	sw		t0,MinHi(t0)	;MinHi = 0
	;inc HourCount
	lw		t2,HourCount(t0);t2 = HourCount
	addi	t2,t2,1			;HourCount++
	sw		t2,HourCount(t0);Store HourCount
	eqi		t3,t2,24		;if(HourCount == 24) t3 = 0
	beqz	t3,NormHour
	
	;hours = 24, reset all hour counters and branch to DispTimer
	sw		t0,HourCount(t0);HourCount = 0
	sw		t0,HourLo(t0)	;HourLo = 0
	sw		t0,HourHi(t0)	;HourHi = 0
	beq		t0,t0,DispTimer
	
NormHour:
	;inc HourLo
	lw		t2,HourLo(t0)	;t2 = HourLo
	addi	t2,t2,256		;HourLo++
	sw		t2,HourLo(t0)	;Store HourLo
	eqi		t3,t2,2560		;if(HourLo == 10*256) t3 = 0
	beqz	t3,DispTimer
	
	;if HourLo = 10
	sw		t0,HourLo(t0)		;HourLo = 0
	;inc HourHi
	lw		t2,HourHi(t0)	;t2 = HourHi
	addi	t2,t2,4096		;HourHi++
	sw		t2,HourHi(t0)		;Store HourLo

DispTimer:
	;display seccount
	lw		t2,SecCount(t0)	;t2 = SecCount
	lw		t3,LEDVal(t0)	;t3 = LEDVal
	or		t2,t2,t3		;Combine SecCount and LEDVal
	sw		t2,0xf808(t0)	;LEDG = Combined
	;display MinLo,MinHi,HourLo,HourHi
	lw		t2,MinLo(t0)	;t2 = MinLo
	add		t3,t2,t0		;t3 = ToDisplay
	lw		t2,MinHi(t0)	;t2 = MinHi
	add		t3,t3,t2		;t3 = ToDisplay
	lw		t2,HourLo(t0)	;t2 = HourLo
	add		t3,t3,t2		;t3 = ToDisplay
	lw		t2,HourHi(t1)	;t2 = HourHi
	add		t3,t3,t2		;t3 = ToDisplay
	;display hourcount
	sw		t3,0xf800(t0)
	beq		t0,t0,IntExit
	
Switch:
	lw		t1,0xF004(t0)	;t1 = switches
	andi	t1,t1,1			;t1 = mask switch 0
	beqz	t1,Soff			;if sw0 is off, goto Soff, else stay on
Son:
	;cheat HalfSec to 50 next go around
	addi	t2,t0,49		;HalfSec++
	sw		t2,HalfSec(t0)	;store HalfSec
	addi	t1,t0,32
	sw		t1,0xF000(t0) ;turn on key interrupts
	beq		t0,t0,SEnd
Soff:
	sw		t0,HalfSec(t0)	;HalfSec = 0
	sw		t0,LEDVal(t0)	;LEDVal = 0
	sw		t0,0xF000(t0)	;turn off key interrupts
SEnd:
	;Reset Switch Interrupts
	addi	t1,t0,0x800
	sw		t1,0xF004(t0)

	beq	t0,t0,IntExit
	
IntExit:
	; Restore register values and return from interrupt
	lw		t0,0(rd)
	lw		t1,4(rd)
	lw		t2,8(rd)
	lw		t3,12(rd)
	lw		a0,16(rd)
	lw		a1,20(rd)
	lw		a2,24(rd)
	lw		a3,28(rd)
	addi	rd,rd,32
	addi	re,re,-1
	reti
	
	.orig   0x400
Main:
	xor		t0,t0,t0 ;0 variable
	; Set system stack pointer
	addi	rd,t0,SysStackTop
	
	;Enable Timer Interrupts @ every 10ms
	;tcnt = 10
	addi	t1,t0,10
	sw		t1,0xF104(t0) 	
	;tctl = 5 (0101), AR=1, IE=1
	addi	t1,t0,5			
	sw		t1,0xF100(t0)	
	
	;Enable Switch Interrupts
	addi	t1,t0,0x800
	sw		t1,0xF004(t0)
	
	;Enable Global Interrupts
	addi	t1,t0,5
	wctl 	ctl0,t1
InfLoop:
	beq 	t0,t0,InfLoop
	
TimerCount:
	nop
SecCount:
	nop
MinLo:
	nop
MinHi:
	nop
HourLo:
	nop
HourHi:
	nop
HourCount:
	nop
HalfSec:
	nop
LEDVal:
	nop

Key:	
	eqi		t1,a1,2
	beqz	t1,Switch		;device isn't key, try switch
	
	lw		t1,0xF000(t0)	;t1 = keys
	andi	t2,t1,1			;t2 = mask key 0
	beqz	t2,K0on			;Key0 is on
	andi	t2,t1,2			;t2 = mask key 1
	beqz	t2,K1on			;Key1 is on
	andi	t2,t1,4			;t2 = mask key 2
	beqz	t2,K2on			;Key2 is on
	andi	t2,t1,8			;t2 = mask key 3
	beqz	t2,K3on			;Key3 is on
	beq		t0,t0,KEnd		;no key? foggedabouddit
	
K0on:
	sw 		t0,SecCount(t0)	;resets seconds
	lw		t1,MinLo(t0)	;t1 = MinLo
	lw		t2,MinHi(t0)	;t2 = MinHi
	
	beqz	t1,KDownHi 		;if(MinLo = 0)
	subi	t1,t1,1			;MinLo --;
	sw		t1,MinLo(t0)	;store MinLo
	beq		t0,t0,KEnd
KDownHi:
	beqz	t2,KDoubleDown	;if(MinHi = 0 && MinLo = 0)
	subi	t2,t2,16		;MinHi -1*16;
	sw		t2,MinHi(t0)	;store MinHi
	addi	t1,t0,9			;t1 = 9
	sw		t1,MinLo(t0)	;MinLo = 9
	beq		t0,t0,KEnd
KDoubleDown:
	addi	t1,t0,80		;t1 = 5*16
	sw		t1,MinHi(t0)	;MinHi = 5*16
	addi	t1,t0,9			;t1 = 9
	sw		t1,MinLo(t0)	;MinLo = 9
	beq		t0,t0,K2on		;dec hour
	
K1on:
	sw 		t0,SecCount(t0)	;resets seconds
	lw		t1,MinLo(t0)	;t1 = MinLo
	lw		t2,MinHi(t0)	;t2 = MinHi

	addi	t1,t1,1
	sw		t1,MinLo(t0)
	addi	t3,t0,10
	beq		t1,t3,KUpHi		;MinLo Wraps @10
	beq		t0,t0,KEnd
KUpHi:
	addi	t2,t2,16
	sw		t0,MinLo(t0)
	sw		t2,MinHi(t0)
	addi	t3,t0,96		;t3 = 6*16
	beq		t2,t3,KDoubleUp	;if(MinLo = 9 && MinHi = 5*16)
	beq		t0,t0,KEnd
KDoubleUp:
	sw		t0,MinHi(t0)	;MinHi = 0
	beq 	t0,t0,K3on		;inc hour

K2on:
	lw		t1,HourCount(t0)
	beqz	t1,KDoubleDownHour
	subi	t1,t1,1
	sw		t1,HourCount(t0)
	lw		t1,HourLo(t0)
	beqz	t1,KDownHourHi
	subi	t1,t1,256
	sw		t1,HourLo(t0)
	beq		t0,t0,KEnd
KDownHourHi:
	lw		t1,HourHi(t0)
	subi	t1,t1,4096		;sub 1*4096
	sw		t1,HourHi(t0)
	addi	t1,t0,2304
	sw		t1,HourLo(t0)
	beq		t0,t0,KEnd
KDoubleDownHour:
	addi	t1,t0,768		;t1 = 3*256
	sw		t1,HourLo(t0)	;HourLo = 3*256
	addi	t1,t0,8192		;t2 = 2*4096
	sw		t1,HourHi(t0)	;HourHi = 2*4096
	addi	t1,t0,23		;t3 = 23
	sw		t1,HourCount(t0);HourCount = 23
	beq		t0,t0,KEnd

K3on:						;inc the hours
	lw		t1,HourCount(t0)
	addi	t1,t1,1
	sw		t1,HourCount(t0)
	addi	t2,t0,24
	beq		t1,t2,KDoubleUpHour ;HourCount == 24
	lw		t1,HourLo(t0)
	addi	t1,t1,256			;HourLo += 1*256
	sw		t1,HourLo(t0)
	addi	t2,t0,2560
	beq		t1,t2,KUpHourHi		;HourLo = 10
	beq		t0,t0,KEnd
KDoubleUpHour:
	sw		t0,HourCount(t0);HourCount = 0
	sw		t0,HourLo(t0)	;HourLo = 0
	sw		t0,HourHi(t0)	;HourHi = 0
	beq		t0,t0,KEnd
KUpHourHi:
	sw		t0,HourLo(t0)	;HourLo = 0
	lw		t1,HourHi(t0)
	addi	t1,t1,4096		;HourHi += 1*4096
	sw		t1,HourHi(t0)
	beq		t0,t0,KEnd
	
KEnd:
	;Reset Key Interrupts
	addi	t1,t0,32
	sw		t1,0xF000(t0)
	
	beq		t0,t0,IntExit